package com.crm.crm.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.crm.crm.constant.CacheConstant;
import com.crm.crm.domain.*;
import com.crm.crm.domain.Login.LoginInfoVo;
import com.crm.crm.domain.Login.LoginUser;
import com.crm.crm.domain.dto.LoginDto;
import com.crm.crm.domain.role.SysRole;
import com.crm.crm.domain.role.SysRoleMenu;
import com.crm.crm.domain.role.SysUserRole;
import com.crm.crm.domain.vo.LoginVo;
import com.crm.crm.domain.vo.business.result.Result;
import com.crm.crm.domain.vo.login.RoutersMeta;
import com.crm.crm.domain.vo.login.RoutersVo;
import com.crm.crm.mapper.*;
import com.crm.crm.mapper.UserRoleMapper;
import com.crm.crm.mapper.role.SysRoleMenuMapper;
import com.crm.crm.mapper.role.SysUserRoleMapper;
import com.crm.crm.service.LoginService;
import com.crm.crm.util.JwtUtils;
import com.crm.crm.util.UserThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class LoginServiceImpl implements LoginService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private LoginMapper loginMapper;

    @Autowired
    private LoginMenuMapper loginMenuMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private SysDeptMapper deptMapper;

    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;


    /**
     * 生成验证码
     *
     * @return
     */
    @Override
    public LoginVo getcaptchaImage() {
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);
        String code = lineCaptcha.getCode();

        String uuid = UUID.fastUUID().toString();

        String upload = lineCaptcha.getImageBase64();


        redisTemplate.opsForValue().set(CacheConstant.LOGIN_CAPTCHA + uuid, code, 3, TimeUnit.MINUTES);

        LoginVo loginVo = new LoginVo();
        loginVo.setImg(upload);
        loginVo.setUuid(uuid.toString());
        return loginVo;
    }

    /**
     * 登录
     *
     * @param loginDto
     * @return
     */
    @Override
    public Result login(LoginDto loginDto) {
        //验证验证码是否正确
        String captcha = redisTemplate.opsForValue().get(CacheConstant.LOGIN_CAPTCHA + loginDto.getUuid());
        if (captcha == null) {
            return Result.error("验证码已过期");
        } else if (!captcha.equalsIgnoreCase(loginDto.getCode())) {
            // 注释掉原逻辑，或根据需求保留错误提示
            return Result.error("验证码错误");
        } else {
            //验证用户名密码
            LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysUser::getUserName, loginDto.getUsername())
                    .eq(SysUser::getPassword, loginDto.getPassword());
            SysUser sysUser = loginMapper.selectOne(wrapper);
            if (ObjectUtil.isEmpty(sysUser)) {
                return Result.error("用户名或密码错误");
            }
            String authorization = JwtUtils.generateJwt(new HashMap<String, Object>() {{
                put("userId", sysUser.getUserId());
                put("username", sysUser.getUserName());
            }});
            return Result.success("登录成功").put("token", authorization);
        }
    }

    /**
     * 获取菜单信息
     *
     * @return
     */
    @Override
    public List<RoutersVo> getRouters() {
        LambdaQueryWrapper<SysMenu> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SysMenu::getMenuType, "M", "C").eq(SysMenu::getVisible, "0");
        List<SysMenu> sysUsers = loginMenuMapper.selectList(wrapper);
        List<RoutersVo> routers = getRouters(sysUsers, 0L);
        return routers;
    }

    /**
     * 获取用户信息
     *
     * @return
     */
    @Override
    public LoginInfoVo getInfo() {
        final boolean[] admin = {false};

        //用token获取用户id，先拿id去查用户表拿到东西
        Long userId = UserThreadLocalUtil.getCurrentUserId();
        SysUser sysUser = userMapper.selectOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserId, userId));

        //拿到部门id，去查部门
        Long deptId = sysUser.getDeptId();
        SysDept deptOld = deptMapper.selectOne(new LambdaQueryWrapper<SysDept>().eq(SysDept::getDeptId, deptId));
        Dept deptNew = new Dept();
        BeanUtils.copyProperties(deptOld, deptNew);

        //去用户角色表查角色ids，拿到角色列表
        List<SysUserRole> sysUserRoles = sysUserRoleMapper.selectList(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, userId));
        ArrayList<Long> roleIds = new ArrayList<>();
        sysUserRoles.forEach(sysUserRole -> {
            Long roleId = sysUserRole.getRoleId();
            roleIds.add(roleId);
        });
        List<SysRole> sysRoles = userRoleMapper.selectList(new LambdaQueryWrapper<SysRole>().in(SysRole::getRoleId, roleIds));
        List<String> roleNames = new ArrayList<>();
        sysRoles.forEach(sysRole -> {
            String roleKey = sysRole.getRoleKey();
            if (roleKey.equals("admin")) {
                admin[0] = true;
            }
            roleNames.add(roleKey);
        });

        //拿到权限列表
        ArrayList<String> permissions = new ArrayList<>();
        if (admin[0] == true) {
            permissions.add("*:*:*");
        } else {
            //用角色id去查角色菜单表id
            List<Long> menuIds = sysRoleMenuMapper.getMenuIds(roleIds);
            log.info("我是menuIds:" + menuIds);
            //用角色菜单id去查菜单表
            List<SysMenu> sysMenus = loginMenuMapper.selectList(new LambdaQueryWrapper<SysMenu>().in(SysMenu::getMenuId, menuIds));
            for (SysMenu sysMenu : sysMenus) {
                String perms = sysMenu.getPerms();
                if (perms != null && !perms.equals("")) {
                    permissions.add(perms);
                }
                permissions.add("indexHome:todoQuery");
                permissions.add("indexHome:list");
                permissions.add("indexHome:businessQuery");
                permissions.add("indexHome:saleQuery");
                permissions.add("indexHome:todayQuery");
                permissions.add("indexHome:funnelQuery");
                permissions.add("indexHome:baseQuery");
            }
        }

        //组装
        LoginInfoVo loginInfoVo = new LoginInfoVo();
        loginInfoVo.setPermissions(permissions);
        loginInfoVo.setRoles(roleNames);

        LoginUser loginUser = new LoginUser();
        BeanUtils.copyProperties(sysUser, loginUser);
        loginUser.setDept(deptNew);
        loginUser.setRoles(sysRoles);
        loginUser.setRoleIds(roleIds);
        loginUser.setAdmin(admin[0]);

        loginInfoVo.setUser(loginUser);
        return loginInfoVo;
    }

    private List<RoutersVo> getRouters(List<SysMenu> sysUsers, long parentId) {
        List<RoutersVo> routersVoList = new ArrayList<>();
        //这里用迭代器,遍历一遍就remove掉
        Iterator<SysMenu> iterator = sysUsers.iterator();
        while (iterator.hasNext()) {
            SysMenu sysMenu = iterator.next();
            if (Integer.valueOf(sysMenu.getVisible()) != 0) {
                iterator.remove();
            }
            if (sysMenu.getParentId() == parentId && sysMenu.getMenuType().equals("M") && sysMenu.getVisible().equals("0")) {
                //是目录
                RoutersVo routersVo = new RoutersVo();
                routersVo.setName(sysMenu.getMenuName());
                routersVo.setPath(sysMenu.getPath());
                routersVo.setHidden(Integer.valueOf(sysMenu.getVisible()) == 0 ? false : true);
                routersVo.setRedirect("noRedirect");
                routersVo.setComponent(sysMenu.getComponent());
                routersVo.setAlwaysShow(Integer.valueOf(sysMenu.getVisible()) == 0 ? false : true);
                RoutersMeta routersMeta = new RoutersMeta();
                routersMeta.setTitle(sysMenu.getMenuName());
                routersMeta.setIcon(sysMenu.getIcon());
                routersMeta.setNoCache(Integer.valueOf(sysMenu.getIsCache()) == 0 ? false : true);
                routersVo.setMeta(routersMeta);

                long newParentId = sysMenu.getMenuId();
                List<RoutersVo> routers = getRouters(sysUsers, newParentId);
                routersVo.setChildren(routers);
                routersVoList.add(routersVo);
                if (Integer.valueOf(sysMenu.getVisible()) != 0) {
                    iterator.remove();
                }
            } else if (sysMenu.getParentId().equals(0L) && sysMenu.getVisible().equals("0")) {
                RoutersVo routersVo = new RoutersVo();
                routersVo.setPath("/");
                routersVo.setHidden(false);
                routersVo.setComponent(sysMenu.getComponent());
                RoutersMeta routersMeta = new RoutersMeta();
                routersMeta.setTitle(sysMenu.getMenuName());
                routersMeta.setIcon(sysMenu.getIcon());
                routersMeta.setNoCache(Integer.valueOf(sysMenu.getIsCache()) == 0 ? false : true);
                routersVo.setMeta(routersMeta);

                ArrayList<RoutersVo> childrens = new ArrayList<>();
                RoutersVo children = new RoutersVo();
                children.setName(sysMenu.getMenuName());
                children.setPath(sysMenu.getPath());
                children.setHidden(false);
                children.setComponent(sysMenu.getComponent());
                RoutersMeta routersMetaChildren = new RoutersMeta();
                routersMetaChildren.setTitle(sysMenu.getMenuName());
                routersMetaChildren.setIcon(sysMenu.getIcon());
                routersMetaChildren.setNoCache(Integer.valueOf(sysMenu.getIsCache()) == 0 ? false : true);
                children.setMeta(routersMetaChildren);
                childrens.add(children);
                routersVo.setChildren(childrens);

                routersVoList.add(routersVo);

                if (Integer.valueOf(sysMenu.getVisible()) != 0) {
                    iterator.remove();
                }
                continue;
            } else if (sysMenu.getParentId() == parentId && sysMenu.getVisible().equals("0")) {
                RoutersVo routersVo = new RoutersVo();
                routersVo.setPath("/");
                routersVo.setHidden(false);
                routersVo.setComponent(sysMenu.getComponent());
                RoutersMeta routersMeta = new RoutersMeta();
                routersMeta.setTitle(sysMenu.getMenuName());
                routersMeta.setIcon(sysMenu.getIcon());
                routersMeta.setNoCache(Integer.valueOf(sysMenu.getIsCache()) == 0 ? false : true);
                routersVo.setMeta(routersMeta);
                routersVoList.add(routersVo);
                if (Integer.valueOf(sysMenu.getVisible()) != 0) {
                    iterator.remove();
                }
            }
        }
        return routersVoList;
    }
}
